package com.tentent.fit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PbCodeGenerator {

    private static final String OUTPUT_BASE_DIR = "src/main/java/com/tentent/fit/pbJavaCode";
    private static final String COMMON_DIR = OUTPUT_BASE_DIR + "/common";
    private static final String DTO_DIR = OUTPUT_BASE_DIR + "/dto";
    private static final String REQ_DIR = OUTPUT_BASE_DIR + "/req";
    private static final String RES_DIR = OUTPUT_BASE_DIR + "/res";
    private static final String ASSEMBLER_DIR = OUTPUT_BASE_DIR + "/assembler";

    public static void main(String[] args) {
        PbCodeGenerator generator = new PbCodeGenerator();
        generator.generateJavaClasses();
    }

    public void generateJavaClasses() {
        try {
            // 删除旧的输出目录
            deleteDirectory(OUTPUT_BASE_DIR);
            
            // 创建新的目录结构
            createDirectories();
            
            // 获取项目根目录
            String projectPath = System.getProperty("user.dir");
            String protoPath = projectPath + "/src/main/resources/proto";
            
            System.out.println("Searching for proto files in: " + protoPath);
            
            // 查找所有proto文件
            Files.walk(Paths.get(protoPath))
                .filter(Files::isRegularFile)
                .filter(path -> path.toString().endsWith(".proto") || path.toString().endsWith(".Proto"))
                .forEach(this::processProtoFile);
                
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void deleteDirectory(String directoryPath) throws IOException {
        Path path = Paths.get(directoryPath);
        if (Files.exists(path)) {
            Files.walk(path)
                .sorted((p1, p2) -> p2.compareTo(p1)) // 从 deepest 开始删除
                .forEach(p -> {
                    try {
                        Files.delete(p);
                    } catch (IOException e) {
                        System.err.println("Failed to delete: " + p);
                    }
                });
        }
    }

    private void createDirectories() throws IOException {
        Files.createDirectories(Paths.get(COMMON_DIR));
        Files.createDirectories(Paths.get(DTO_DIR));
        Files.createDirectories(Paths.get(REQ_DIR));
        Files.createDirectories(Paths.get(RES_DIR));
        Files.createDirectories(Paths.get(ASSEMBLER_DIR));
        System.out.println("Created directory structure");
    }

    private void processProtoFile(Path protoFile) {
        System.out.println("Processing proto file: " + protoFile.getFileName());
        
        // 收集所有消息信息
        List<MessageInfo> messages = collectMessages(protoFile);
        
        // 为每个proto文件生成一个Assembler类
        generateAssemblerClass(protoFile, messages);
        
        // 处理每个消息
        for (MessageInfo message : messages) {
            // 检查是否为HeaderParam消息
            if ("HeaderParam".equals(message.getName())) {
                // 生成BaseRequestDTO和BaseResponseDTO类到common目录
                generateBaseDTOClasses(message.getComment(), message.getFields());
                System.out.println("Generated BaseRequestDTO and BaseResponseDTO classes");
            }
            // 检查是否以Req结尾
            else if (message.getName().endsWith("Req")) {
                // 生成RequestDTO类到req目录
                String className = message.getName().replaceAll("Req$", "RequestDTO");
                generateRequestDTOClass(className, message.getComment(), message.getFields());
                System.out.println("Generated RequestDTO class: " + className);
            }
            // 检查是否以Resp结尾
            else if (message.getName().endsWith("Resp")) {
                // 生成ResponseDTO类到res目录
                String className = message.getName().replaceAll("Resp$", "ResponseDTO");
                generateResponseDTOClass(className, message.getComment(), message.getFields());
                System.out.println("Generated ResponseDTO class: " + className);
            }
            // 处理普通message（既不以Req也不以Resp结尾，且不是HeaderParam）
            else if (!"PageInfo".equals(message.getName())) {
                // 生成普通Java类到dto目录，类名与message名相同
                generateRegularClass(message.getName(), message.getComment(), message.getFields());
                System.out.println("Generated regular class: " + message.getName());
            } else {
                // 生成PageInfo类到common目录
                generatePageInfoClass(message.getName(), message.getComment(), message.getFields());
                System.out.println("Generated PageInfo class: " + message.getName());
            }
        }
    }

    private List<MessageInfo> collectMessages(Path protoFile) {
        List<MessageInfo> messages = new ArrayList<>();
        
        try (BufferedReader reader = new BufferedReader(new FileReader(protoFile.toFile()))) {
            String line;
            String messageName = "";
            String messageComment = ""; // 消息注释
            boolean inMessage = false;
            List<FieldInfo> fields = new ArrayList<>();
            
            while ((line = reader.readLine()) != null) {
                // 查找message定义前的注释
                if (line.trim().startsWith("//") && !inMessage) {
                    messageComment = line.trim().substring(2).trim();
                }
                // 查找message定义
                else if (line.contains("message")) {
                    Pattern messagePattern = Pattern.compile("\\s*message\\s+(\\w+)\\s*\\{");
                    Matcher messageMatcher = messagePattern.matcher(line);
                    
                    if (messageMatcher.find()) {
                        messageName = messageMatcher.group(1);
                        inMessage = true;
                        System.out.println("Found message: " + messageName);
                        
                        // 重置字段列表
                        fields = new ArrayList<>();
                    }
                }
                // 在message内部查找字段定义
                else if (inMessage && line.contains(";")) {
                    FieldInfo field = parseField(line);
                    if (field != null) {
                        fields.add(field);
                    }
                }
                // 结束message定义
                else if (inMessage && line.contains("}")) {
                    messages.add(new MessageInfo(messageName, messageComment, fields));
                    inMessage = false;
                    messageComment = ""; // 重置消息注释
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        return messages;
    }

    private void generateAssemblerClass(Path protoFile, List<MessageInfo> messages) {
        // 获取文件名（不含扩展名）
        String fileName = protoFile.getFileName().toString();
        String baseName = fileName.substring(0, fileName.lastIndexOf('.'));
        
        // 转换为驼峰命名并添加后缀，首字母大写
        String className = toCamelCaseWithCapital(baseName) + "TrpcAssembler";
        
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.assembler;\n\n");
        
        // 添加需要的导入语句
        Set<String> imports = new HashSet<>();
        imports.add("import com.tentent.fit.pbJavaCode.common.BaseRequestDTO;\n");
        imports.add("import com.tentent.fit.pbJavaCode.common.BaseResponseDTO;\n");
        
        // 收集需要导入的普通类
        for (MessageInfo message : messages) {
            if (!message.getName().endsWith("Req") && 
                !message.getName().endsWith("Resp") && 
                !"HeaderParam".equals(message.getName()) &&
                !"PageInfo".equals(message.getName())) {
                imports.add("import com.tentent.fit.pbJavaCode.dto." + message.getName() + ";\n");
            }
        }
        
        for (MessageInfo message : messages) {
            if (message.getName().endsWith("Req")) {
                imports.add("import com.tentent.fit.pbJavaCode.req." + message.getName().replaceAll("Req$", "RequestDTO") + ";\n");
            } else if (message.getName().endsWith("Resp")) {
                imports.add("import com.tentent.fit.pbJavaCode.res." + message.getName().replaceAll("Resp$", "ResponseDTO") + ";\n");
            }
        }
        
        for (String imp : imports) {
            classContent.append(imp);
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("import org.apache.commons.lang3.StringUtils;\n\n");
        classContent.append("@Data\n");
        classContent.append("public class ").append(className).append(" {\n\n");
        
        // 生成普通类的转换方法
        generateRegularClassConvertMethods(classContent, messages);
        
        // 生成转换方法
        for (MessageInfo message : messages) {
                if (message.getName().endsWith("Req")) {
                    String dtoName = message.getName().replaceAll("Req$", "RequestDTO");
                    classContent.append("    public static ").append(dtoName).append(" convertTo").append(dtoName).append("(").append(message.getName()).append(" pbReq) {\n");
                    classContent.append("        if (pbReq == null) {\n");
                    classContent.append("            return null;\n");
                    classContent.append("        }\n");
                    classContent.append("        ").append(dtoName).append(" dto = new ").append(dtoName).append("();\n");
                    
                    // 添加字段转换逻辑
                    for (FieldInfo field : message.getFields()) {
                        String fieldName = toCamelCase(field.getName());
                        if ("header_param".equals(field.getName())) { // 处理header_param字段
                            classContent.append("        // 从header_param转换BaseRequestDTO字段\n");
                            classContent.append("        HeaderParam headerParam = pbReq.getHeaderParam();\n");
                            classContent.append("        if (headerParam != null) {\n");
                            classContent.append("            dto.setAppid(headerParam.getAppid());\n");
                            classContent.append("            dto.setSign(headerParam.getSign());\n");
                            classContent.append("            dto.setOpTimestamp(headerParam.getOpTimestamp());\n");
                            classContent.append("        }\n");
                        } else {
                            // 处理其他字段
                            if ("PageInfo".equals(field.getType())) { // 特殊处理PageInfo字段
                                classContent.append("        // 转换PageInfo字段\n");
                                classContent.append("        com.tentent.fit.pbJavaCode.common.PageInfo pageInfoDTO = convertPageInfoToDTO(pbReq.getPageInfo());\n");
                                classContent.append("        dto.setPageInfo(pageInfoDTO);\n");
                            } else {
                                classContent.append("        dto.set").append(capitalizeFirstLetter(fieldName)).append("(pbReq.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                            }
                        }
                    }
                    
                    classContent.append("        return dto;\n");
                    classContent.append("    }\n\n");
                    
                    // 添加PageInfo转换方法
                    classContent.append("    private static com.tentent.fit.pbJavaCode.common.PageInfo convertPageInfoToDTO(PageInfo pbPageInfo) {\n");
                    classContent.append("        if (pbPageInfo == null) {\n");
                    classContent.append("            return null;\n");
                    classContent.append("        }\n");
                    classContent.append("        com.tentent.fit.pbJavaCode.common.PageInfo dto = new com.tentent.fit.pbJavaCode.common.PageInfo();\n");
                    classContent.append("        dto.setPageNum(pbPageInfo.getPageNum());\n");
                    classContent.append("        dto.setPageSize(pbPageInfo.getPageSize());\n");
                    classContent.append("        dto.setCurrentPage(pbPageInfo.getCurrentPage());\n");
                    classContent.append("        dto.setCurrentPageSize(pbPageInfo.getCurrentPageSize());\n");
                    classContent.append("        dto.setTotalCount(pbPageInfo.getTotalCount());\n");
                    classContent.append("        dto.setTotalPage(pbPageInfo.getTotalPage());\n");
                    classContent.append("        return dto;\n");
                    classContent.append("    }\n\n");
            } else if (message.getName().endsWith("Resp")) {
                String dtoName = message.getName().replaceAll("Resp$", "ResponseDTO");
                
                classContent.append("    public static ").append(message.getName()).append(" convertTo").append(message.getName()).append("(").append(dtoName).append(" responseDTO) {\n");
                classContent.append("        if (responseDTO == null) {\n");
                classContent.append("            return null;\n");
                classContent.append("        }\n");
                classContent.append("        ").append(message.getName()).append(".Builder builder = ").append(message.getName()).append(".newBuilder();\n");
                
                // 添加字段转换逻辑
                for (FieldInfo field : message.getFields()) {
                    String fieldName = toCamelCase(field.getName());
                    if ("header_param".equals(field.getName())) { // 处理header_param字段
                        classContent.append("        // 从BaseResponseDTO转换header_param字段\n");
                        classContent.append("        HeaderParam.Builder headerParamBuilder = HeaderParam.newBuilder();\n");
                        classContent.append("        if (responseDTO.getAppid() != null) {\n");
                        classContent.append("            headerParamBuilder.setAppid(responseDTO.getAppid());\n");
                        classContent.append("        }\n");
                        classContent.append("        if (responseDTO.getSign() != null) {\n");
                        classContent.append("            headerParamBuilder.setSign(responseDTO.getSign());\n");
                        classContent.append("        }\n");
                        classContent.append("        if (responseDTO.getOpTimestamp() != null) {\n");
                        classContent.append("            headerParamBuilder.setOpTimestamp(responseDTO.getOpTimestamp());\n");
                        classContent.append("        }\n");
                        classContent.append("        builder.setHeaderParam(headerParamBuilder.build());\n");
                    } else {
                        // 处理其他字段
                        if ("PageInfo".equals(field.getType())) { // 特殊处理PageInfo字段
                            classContent.append("        // 转换PageInfo字段\n");
                            classContent.append("        PageInfo pbPageInfo = convertPageInfoToPb(responseDTO.getPageInfo());\n");
                            classContent.append("        builder.setPageInfo(pbPageInfo);\n");
                        } else if ("string".equals(field.getType())) {
                            // 对于string类型，使用StringUtils.isNotEmpty检查
                            classContent.append("        if (StringUtils.isNotEmpty(responseDTO.get").append(capitalizeFirstLetter(fieldName)).append("())) {\n");
                            classContent.append("            builder.set").append(capitalizeFirstLetter(fieldName)).append("(responseDTO.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                            classContent.append("        }\n");
                        } else if (isPrimitiveType(field.getType())) {
                            // 对于其他基本类型，需要检查是否为null
                            classContent.append("        if (responseDTO.get").append(capitalizeFirstLetter(fieldName)).append("() != null) {\n");
                            classContent.append("            builder.set").append(capitalizeFirstLetter(fieldName)).append("(responseDTO.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                            classContent.append("        }\n");
                        } else {
                            // 对于对象类型，直接设置
                            classContent.append("        builder.set").append(capitalizeFirstLetter(fieldName)).append("(responseDTO.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                        }
                    }
                }
                
                classContent.append("        return builder.build();\n");
                classContent.append("    }\n\n");
                
                // 添加PageInfo转换方法
                classContent.append("    private static PageInfo convertPageInfoToPb(com.tentent.fit.pbJavaCode.common.PageInfo dto) {\n");
                classContent.append("        if (dto == null) {\n");
                classContent.append("            return null;\n");
                classContent.append("        }\n");
                classContent.append("        PageInfo.Builder builder = PageInfo.newBuilder();\n");
                classContent.append("        if (dto.getPageNum() != null) {\n");
                classContent.append("            builder.setPageNum(dto.getPageNum());\n");
                classContent.append("        }\n");
                classContent.append("        if (dto.getPageSize() != null) {\n");
                classContent.append("            builder.setPageSize(dto.getPageSize());\n");
                classContent.append("        }\n");
                classContent.append("        if (dto.getCurrentPage() != null) {\n");
                classContent.append("            builder.setCurrentPage(dto.getCurrentPage());\n");
                classContent.append("        }\n");
                classContent.append("        if (dto.getCurrentPageSize() != null) {\n");
                classContent.append("            builder.setCurrentPageSize(dto.getCurrentPageSize());\n");
                classContent.append("        }\n");
                classContent.append("        if (dto.getTotalCount() != null) {\n");
                classContent.append("            builder.setTotalCount(dto.getTotalCount());\n");
                classContent.append("        }\n");
                classContent.append("        if (dto.getTotalPage() != null) {\n");
                classContent.append("            builder.setTotalPage(dto.getTotalPage());\n");
                classContent.append("        }\n");
                classContent.append("        return builder.build();\n");
                classContent.append("    }\n\n");
            }
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = ASSEMBLER_DIR + "/" + className + ".java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created assembler file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成普通类的转换方法
     * @param classContent 类内容构建器
     * @param messages 消息列表
     */
    private void generateRegularClassConvertMethods(StringBuilder classContent, List<MessageInfo> messages) {
        for (MessageInfo message : messages) {
            // 只处理普通类（不以Req或Resp结尾，且不是HeaderParam和PageInfo）
            if (!message.getName().endsWith("Req") && 
                !message.getName().endsWith("Resp") && 
                !"HeaderParam".equals(message.getName()) &&
                !"PageInfo".equals(message.getName())) {
                
                String className = message.getName();
                
                // 生成从pb到java的转换方法
                classContent.append("    public static com.tentent.fit.pbJavaCode.dto.").append(className).append(" convert").append(className).append("FromPbToDTO(").append(className).append(" pbProto) {\n");
                classContent.append("        if (pbProto == null) {\n");
                classContent.append("            return null;\n");
                classContent.append("        }\n");
                classContent.append("        com.tentent.fit.pbJavaCode.dto.").append(className).append(" dto = new com.tentent.fit.pbJavaCode.dto.").append(className).append("();\n");
                
                // 添加字段转换逻辑
                for (FieldInfo field : message.getFields()) {
                    String fieldName = toCamelCase(field.getName());
                    classContent.append("        dto.set").append(capitalizeFirstLetter(fieldName)).append("(pbProto.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                }
                
                classContent.append("        return dto;\n");
                classContent.append("    }\n\n");
                
                // 生成从java到pb的转换方法
                classContent.append("    public static ").append(className).append(" convert").append(className).append("FromDTOToPb(com.tentent.fit.pbJavaCode.dto.").append(className).append(" dto) {\n");
                classContent.append("        if (dto == null) {\n");
                classContent.append("            return null;\n");
                classContent.append("        }\n");
                classContent.append("        ").append(className).append(".Builder builder = ").append(className).append(".newBuilder();\n");
                
                // 添加字段转换逻辑
                for (FieldInfo field : message.getFields()) {
                    String fieldName = toCamelCase(field.getName());
                    if ("string".equals(field.getType())) {
                        // 对于string类型，使用StringUtils.isNotEmpty检查
                        classContent.append("        if (StringUtils.isNotEmpty(dto.get").append(capitalizeFirstLetter(fieldName)).append("())) {\n");
                        classContent.append("            builder.set").append(capitalizeFirstLetter(fieldName)).append("(dto.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                        classContent.append("        }\n");
                    } else if (isPrimitiveType(field.getType())) {
                        // 对于其他基本类型，需要检查是否为null
                        classContent.append("        if (dto.get").append(capitalizeFirstLetter(fieldName)).append("() != null) {\n");
                        classContent.append("            builder.set").append(capitalizeFirstLetter(fieldName)).append("(dto.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                        classContent.append("        }\n");
                    } else {
                        // 对于对象类型，直接设置
                        classContent.append("        builder.set").append(capitalizeFirstLetter(fieldName)).append("(dto.get").append(capitalizeFirstLetter(fieldName)).append("());\n");
                    }
                }
                
                classContent.append("        return builder.build();\n");
                classContent.append("    }\n\n");
            }
        }
    }
    
    /**
     * 判断是否为基本类型
     * @param type 类型名称
     * @return 是否为基本类型
     */
    private boolean isPrimitiveType(String type) {
        return "int32".equals(type) || "int64".equals(type) || "string".equals(type) || "bool".equals(type);
    }

    private FieldInfo parseField(String line) {
        // 解析字段定义，例如: string act_id = 3; // 活动ID
        // 或者: repeated ActInfo act_info = 3;
        Pattern fieldPattern = Pattern.compile("\\s*(?:(repeated)\\s+)?(\\w+)\\s+(\\w+)\\s*=\\s*\\d+\\s*;\\s*(?://\\s*(.+))?");
        Matcher fieldMatcher = fieldPattern.matcher(line);
        
        if (fieldMatcher.find()) {
            String repeated = fieldMatcher.group(1);
            String type = fieldMatcher.group(2);
            String name = fieldMatcher.group(3);
            String comment = fieldMatcher.group(4);
            
            // 如果没有注释，使用字段名作为注释
            if (comment == null || comment.isEmpty()) {
                comment = name;
            }
            
            boolean isRepeated = "repeated".equals(repeated);
            return new FieldInfo(type, name, comment, isRepeated);
        }
        
        return null;
    }

    private boolean hasRepeatedFields(List<FieldInfo> fields) {
        for (FieldInfo field : fields) {
            if (field.isRepeated()) {
                return true;
            }
        }
        return false;
    }

    private Set<String> getCustomFieldTypes(List<FieldInfo> fields) {
        Set<String> customTypes = new HashSet<>();
        for (FieldInfo field : fields) {
            String type = field.getType();
            // 检查是否为自定义类型（非基本类型）
            if (!"int32".equals(type) && !"int64".equals(type) && 
                !"string".equals(type) && !"bool".equals(type)) {
                customTypes.add(type);
            }
        }
        return customTypes;
    }

    private void generateBaseDTOClasses(String classComment, List<FieldInfo> fields) {
        // 生成BaseRequestDTO类
        generateBaseRequestDTO(classComment, fields);
        
        // 生成BaseResponseDTO类
        generateBaseResponseDTO(classComment, fields);
    }
    
    private void generateBaseRequestDTO(String classComment, List<FieldInfo> fields) {
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.common;\n\n");
        
        // 添加导入语句
        boolean hasList = hasRepeatedFields(fields);
        Set<String> customTypes = getCustomFieldTypes(fields);
        
        if (hasList) {
            classContent.append("import java.util.List;\n");
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("\n");
        classContent.append("/**\n");
        classContent.append(" * ").append(classComment).append("\n");
        classContent.append(" */\n");
        classContent.append("@Data\n");
        classContent.append("public class BaseRequestDTO {\n\n");
        
        // 生成字段
        for (FieldInfo field : fields) {
            classContent.append("    /**\n");
            classContent.append("     * ").append(field.getComment()).append("\n");
            classContent.append("     */\n");
            classContent.append("    private ").append(mapProtoTypeToJava(field.getType(), field.isRepeated())).append(" ").append(toCamelCase(field.getName())).append(";\n\n");
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = COMMON_DIR + "/BaseRequestDTO.java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void generateBaseResponseDTO(String classComment, List<FieldInfo> fields) {
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.common;\n\n");
        
        // 添加导入语句
        boolean hasList = hasRepeatedFields(fields);
        Set<String> customTypes = getCustomFieldTypes(fields);
        
        if (hasList) {
            classContent.append("import java.util.List;\n");
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("\n");
        classContent.append("/**\n");
        classContent.append(" * ").append(classComment).append("\n");
        classContent.append(" */\n");
        classContent.append("@Data\n");
        classContent.append("public class BaseResponseDTO {\n\n");
        
        // 生成字段
        for (FieldInfo field : fields) {
            classContent.append("    /**\n");
            classContent.append("     * ").append(field.getComment()).append("\n");
            classContent.append("     */\n");
            classContent.append("    private ").append(mapProtoTypeToJava(field.getType(), field.isRepeated())).append(" ").append(toCamelCase(field.getName())).append(";\n\n");
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = COMMON_DIR + "/BaseResponseDTO.java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void generatePageInfoClass(String className, String classComment, List<FieldInfo> fields) {
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.common;\n\n");
        
        // 添加导入语句
        boolean hasList = hasRepeatedFields(fields);
        
        if (hasList) {
            classContent.append("import java.util.List;\n");
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("\n");
        classContent.append("/**\n");
        classContent.append(" * ").append(classComment).append("\n");
        classContent.append(" */\n");
        classContent.append("@Data\n");
        classContent.append("public class ").append(className).append(" {\n\n");
        
        // 生成字段
        for (FieldInfo field : fields) {
            classContent.append("    /**\n");
            classContent.append("     * ").append(field.getComment()).append("\n");
            classContent.append("     */\n");
            classContent.append("    private ").append(mapProtoTypeToJava(field.getType(), field.isRepeated())).append(" ").append(toCamelCase(field.getName())).append(";\n\n");
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = COMMON_DIR + "/" + className + ".java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void generateRequestDTOClass(String className, String classComment, List<FieldInfo> fields) {
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.req;\n\n");
        
        // 添加导入语句
        boolean hasList = hasRepeatedFields(fields);
        Set<String> customTypes = getCustomFieldTypes(fields);
        
        // 添加自定义类型的导入语句（从common包导入BaseRequestDTO）
        classContent.append("import com.tentent.fit.pbJavaCode.common.BaseRequestDTO;\n");
        
        // 添加自定义类型的导入语句
        for (FieldInfo field : fields) {
            String type = field.getType();
            // 跳过header_param字段
            if ("header_param".equals(field.getName())) {
                continue;
            }
            // 检查是否为自定义类型（非基本类型）
            if (!"int32".equals(type) && !"int64".equals(type) && 
                !"string".equals(type) && !"bool".equals(type)) {
                // 如果是PageInfo，从common包导入
                if ("PageInfo".equals(type)) {
                    classContent.append("import com.tentent.fit.pbJavaCode.common.PageInfo;\n");
                } else {
                    // 其他自定义类型从dto包导入
                    classContent.append("import com.tentent.fit.pbJavaCode.dto.").append(type).append(";\n");
                }
            }
        }
        
        if (hasList) {
            classContent.append("import java.util.List;\n");
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("\n");
        classContent.append("/**\n");
        classContent.append(" * ").append(classComment).append("\n");
        classContent.append(" */\n");
        classContent.append("@Data\n");
        classContent.append("public class ").append(className).append(" extends BaseRequestDTO {\n\n");
        
        // 生成字段（排除header_param字段，因为它已经在BaseRequestDTO中定义）
        for (FieldInfo field : fields) {
            // 跳过header_param字段，因为它已经在BaseRequestDTO中定义
            if ("header_param".equals(field.getName())) {
                continue;
            }
            
            classContent.append("    /**\n");
            classContent.append("     * ").append(field.getComment()).append("\n");
            classContent.append("     */\n");
            classContent.append("    private ").append(mapProtoTypeToJava(field.getType(), field.isRepeated())).append(" ").append(toCamelCase(field.getName())).append(";\n\n");
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = REQ_DIR + "/" + className + ".java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void generateResponseDTOClass(String className, String classComment, List<FieldInfo> fields) {
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.res;\n\n");
        
        // 添加导入语句
        boolean hasList = hasRepeatedFields(fields);
        Set<String> customTypes = getCustomFieldTypes(fields);
        
        // 添加自定义类型的导入语句（从common包导入BaseResponseDTO）
        classContent.append("import com.tentent.fit.pbJavaCode.common.BaseResponseDTO;\n");
        
        // 添加自定义类型的导入语句
        for (FieldInfo field : fields) {
            String type = field.getType();
            // 跳过header_param字段
            if ("header_param".equals(field.getName())) {
                continue;
            }
            // 检查是否为自定义类型（非基本类型）
            if (!"int32".equals(type) && !"int64".equals(type) && 
                !"string".equals(type) && !"bool".equals(type)) {
                // 如果是PageInfo，从common包导入
                if ("PageInfo".equals(type)) {
                    classContent.append("import com.tentent.fit.pbJavaCode.common.PageInfo;\n");
                } else {
                    // 其他自定义类型从dto包导入
                    classContent.append("import com.tentent.fit.pbJavaCode.dto.").append(type).append(";\n");
                }
            }
        }
        
        if (hasList) {
            classContent.append("import java.util.List;\n");
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("\n");
        classContent.append("/**\n");
        classContent.append(" * ").append(classComment).append("\n");
        classContent.append(" */\n");
        classContent.append("@Data\n");
        classContent.append("public class ").append(className).append(" extends BaseResponseDTO {\n\n");
        
        // 生成字段（排除header_param字段，因为它已经在BaseResponseDTO中定义）
        for (FieldInfo field : fields) {
            // 跳过header_param字段，因为它已经在BaseResponseDTO中定义
            if ("header_param".equals(field.getName())) {
                continue;
            }
            
            classContent.append("    /**\n");
            classContent.append("     * ").append(field.getComment()).append("\n");
            classContent.append("     */\n");
            classContent.append("    private ").append(mapProtoTypeToJava(field.getType(), field.isRepeated())).append(" ").append(toCamelCase(field.getName())).append(";\n\n");
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = RES_DIR + "/" + className + ".java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void generateRegularClass(String className, String classComment, List<FieldInfo> fields) {
        StringBuilder classContent = new StringBuilder();
        classContent.append("package com.tentent.fit.pbJavaCode.dto;\n\n");
        
        // 添加导入语句
        boolean hasList = hasRepeatedFields(fields);
        Set<String> customTypes = getCustomFieldTypes(fields);
        
        // 添加自定义类型的导入语句
        for (FieldInfo field : fields) {
            String type = field.getType();
            // 检查是否为自定义类型（非基本类型）
            if (!"int32".equals(type) && !"int64".equals(type) && 
                !"string".equals(type) && !"bool".equals(type)) {
                classContent.append("import com.tentent.fit.pbJavaCode.dto.").append(type).append(";\n");
            }
        }
        
        if (hasList) {
            classContent.append("import java.util.List;\n");
        }
        
        classContent.append("import lombok.Data;\n");
        classContent.append("\n");
        classContent.append("/**\n");
        classContent.append(" * ").append(classComment).append("\n");
        classContent.append(" */\n");
        classContent.append("@Data\n");
        classContent.append("public class ").append(className).append(" {\n\n");
        
        // 生成字段
        for (FieldInfo field : fields) {
            classContent.append("    /**\n");
            classContent.append("     * ").append(field.getComment()).append("\n");
            classContent.append("     */\n");
            classContent.append("    private ").append(mapProtoTypeToJava(field.getType(), field.isRepeated())).append(" ").append(toCamelCase(field.getName())).append(";\n\n");
        }
        
        classContent.append("}\n");
        
        // 写入文件
        try {
            String filePath = DTO_DIR + "/" + className + ".java";
            Files.write(Paths.get(filePath), classContent.toString().getBytes());
            System.out.println("Successfully created file: " + filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private String mapProtoTypeToJava(String protoType, boolean isRepeated) {
        String javaType;
        switch (protoType) {
            case "int32":
            case "int64":
                javaType = "Long";
                break;
            case "string":
                javaType = "String";
                break;
            case "bool":
                javaType = "Boolean";
                break;
            default:
                // 对于自定义类型，保持原样
                javaType = protoType;
                break;
        }
        
        // 如果是repeated类型，包装成List
        if (isRepeated) {
            return "List<" + javaType + ">";
        }
        
        return javaType;
    }
    
    private String toCamelCase(String fieldName) {
        // 将下划线命名转换为驼峰命名
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = false;
        
        for (char c : fieldName.toCharArray()) {
            if (c == '_') {
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(c);
                }
            }
        }
        
        return result.toString();
    }
    
    private String capitalizeFirstLetter(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
    
    private String toCamelCaseWithCapital(String fieldName) {
        // 将下划线命名转换为驼峰命名，首字母大写
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = true; // 首字母大写
        
        for (char c : fieldName.toCharArray()) {
            if (c == '_') {
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(c);
                }
            }
        }
        
        return result.toString();
    }
    
    // 字段信息内部类
    private static class FieldInfo {
        private String type;
        private String name;
        private String comment;
        private boolean isRepeated;
        
        public FieldInfo(String type, String name, String comment, boolean isRepeated) {
            this.type = type;
            this.name = name;
            this.comment = comment;
            this.isRepeated = isRepeated;
        }
        
        public String getType() { return type; }
        public String getName() { return name; }
        public String getComment() { return comment; }
        public boolean isRepeated() { return isRepeated; }
    }
    
    // 消息信息内部类
    private static class MessageInfo {
        private String name;
        private String comment;
        private List<FieldInfo> fields;
        
        public MessageInfo(String name, String comment, List<FieldInfo> fields) {
            this.name = name;
            this.comment = comment;
            this.fields = fields;
        }
        
        public String getName() { return name; }
        public String getComment() { return comment; }
        public List<FieldInfo> getFields() { return fields; }
    }
}